'use strict';
const request = require('request');
const fs = require('fs');
const cheerio = require('cheerio');
const crypto = require('crypto');
const ProgressBar = require('progress');
const Promise = require('bluebird');
try {
    fs.statSync('./sex');
} catch (e) {
    fs.mkdirSync('./sex');
}

function visitSite(url) {
    return new Promise((resolve, reject) => {
        request(url, function(error, response, body) {
            if (error) {
                return reject(error);
            } else if (response.statusCode != 200) {
                return reject('request fail ' + response.statusCode);
            }
            resolve(response.body);
        })
    })
};
//解析首页http://www.mm131.com/
function analyzeMain(html) {
    return new Promise((resolve, reject) => {
        let $ = cheerio.load(html);
        let arr = [];
        $('li.left-list_li > a').each((i, e) => {
            arr.push($(e).attr('href'));
        });
        $('.hot.public-box ').find('a').each((i, e) => {
            arr.push($(e).attr('href'));
        });
        $('.channel.public-box').find('a').each((i, e) => {
            arr.push($(e).attr('href'));
        })
        resolve(arr);
    });
}

function analyzeDetails(html) {
    return new Promise((resolve, reject) => {
        let $ = cheerio.load(html);
        let tag = $('.content-pic > a').html();
        let a = tag.indexOf('src="')
        let b = tag.indexOf('"', a + 5);
        let imageUrl = tag.substring(a + 5, b);
        let numSrc = $('span.page-ch').text()
        numSrc = numSrc.substring(2, numSrc.length - 1);
        let num = parseInt(numSrc, 10);
        let front = imageUrl.substr(0, imageUrl.lastIndexOf('/') + 1);
        let after = imageUrl.substr(imageUrl.lastIndexOf('.'));
        let images = [];
        for (let i = 1; i <= num; i++) {
            images.push(front + i + after);
        }
        resolve(images);
    })
}

function downloadImage(url) {
    return new Promise((resolve, reject) => {
        let fileName = crypto.createHash('md5').update(url).digest('hex');
        let savePath = './sex/' + fileName + '.jpg';
        fs.stat(savePath, (err) => {
            if (!err) {
                resolve(0); //已存在，不用下
                bar.tick();
            }
            let ws = fs.createWriteStream(savePath);
            //文件资源描述符被耗完：Error: EMFILE: too many open files
            ws.on('finish', () => {
                resolve(1); //下载完成
                bar.tick();
            })
            request.get(url).on('error', function(err) {
                reject(-1)
                bar.tick()
            }).pipe(ws);
        });
    })
}
let bar;
visitSite('http://www.mm131.com/').then(html => analyzeMain(html)).then(urls => Promise.all(urls.map(url => visitSite(url).then(html => analyzeDetails(html))))).then(arrs => {
    let arr = [];
    arrs.forEach(v => arr = arr.concat(v))
    return arr;
}).then(urls => {
    console.info('爬了' + urls.length + '条图片地址');
    bar = new ProgressBar('  downloading [:bar] :percent', {
        complete: '=',
        incomplete: ' ',
        width: 50,
        total: urls.length
    });
    //TODO async.parallelLimit
    return Promise.map(urls,(url)=>downloadImage(url),{concurrency: 100})
    // let promises = urls.map(url => downloadImage(url))
    // return Promise.all(promises,);
}).then((info) => {
    console.info('very nice');
    let downloaded = undownloaded = 0;
    info.forEach((v) => {
        if (v == 1) {
            downloaded++;
        } else {
            undownloaded++;
        }
    })
    console.log('下载了' + downloaded + '张,跳过了' + undownloaded + "张")
}).catch(err => console.log(err))